package DataFile;

import java.nio.ByteBuffer;
import java.util.LinkedList;

//import ClassData.ConstantPool;
//import ClassData.ConstantPoolInfo;
import ClassData.FieldInfo;

/**
 * 
 * 
 * @note rewritten by Dominik Ollesz
 */
public class Structure_FieldTable extends Structure_Template {

	private LinkedList<Structure_FieldData> fieldTable = 
		new LinkedList<Structure_FieldData>() ;  

	public Structure_FieldTable(FieldInfo[] fields) {
		for (FieldInfo field : fields) {
			fieldTable.add(new Structure_FieldData(field));
		}
	}

	protected int setBaseAddress(int newBaseAdress) {
		while ((newBaseAdress%4)!=0) {
			newBaseAdress++;
		}
		baseAdress=newBaseAdress;
		return(baseAdress+getMemorySize());
	}

	/**
	 * @return Elements inside table.
	 */
	public int size() {
		return(fieldTable.size());	
	}

	public Structure_FieldData get(int index) {
		return(fieldTable.get(index));
	}

	/**
	 * <table>
	 *   <thead><tr><th>Attribute</th><th>Symbolic</th><th>Bytes</th></tr></thead>
	 *   <tbody>
	 *   <tr> <td>Fields count</td>  <td>SHORT_WIDTH</td>    <td>2</td> </tr>
	 *   <tr> <td>Dummy</td>         <td>SHORT_WIDTH</td>    <td>2</td> </tr>
	 *   <tr> <td>Addresses</td>     <td>n*ADRESS_WIDTH</td> <td>n*4</td> </tr>
	 *   <tr> <td></td>              <td></td>               <td><b>4+n*4</b></td></tr>
	 *   </tbody>
	 * </table>
	 */
	protected int getMemorySize() {
		int mySize;
		
		mySize =SHORT_WIDTH; // fields count
		mySize+=SHORT_WIDTH; // dummy
		mySize+=(fieldTable.size()*ADRESS_WIDTH);
		
		return(mySize);
	}

	/**
	 * @return Bytes of all table entries.
	 */
	protected int getTableDataMemorySize() {
		int mySize;
		int counter;
	
		mySize=0;
		
		for (counter=0;counter < fieldTable.size();counter++) {
			mySize+=fieldTable.get(counter).getMemorySize();
		}
		return(mySize);
	}

	protected String getMemoryMapAsString() {
		String returnString;
		
		returnString="\nField Table : Base Adress - ";
		returnString+=getAdressAsHexString(baseAdress);
		returnString+=" : table size - "+getMemorySize();
		returnString+=" : data size - "+getTableDataMemorySize();
		
		returnString+="\n";
		
		return(returnString);
	}
	
	/**
	 *  Writes data into memory file
	 *  @author Tavin
	 *  @param fileData buffer for data 
	 *  @note changed by Dominik Ollesz
	 */
	public void writeData(ByteBuffer fileData){
		fileData.position(baseAdress-DataFileCreator.BASE_MEMORY_ADRESS);
		
		fileData.putShort((short)fieldTable.size());         //  2 Bytes: Size
		fileData.putShort((short)0);	                     //  2 Bytes: Dummy
		
		for (Structure_FieldData fieldData : fieldTable) {   // Size x
			fileData.putInt(fieldData.getBaseAddress());     //  4 Bytes
		}                                                    //-----------------
                                                             //  4 Bytes  (size+1)
		
		for (Structure_FieldData fieldData : fieldTable) {   // Size x   
			fieldData.writeData(fileData);                   //  sizeof(Structure_FieldData)
		}		
	}
	
	/*
	public void writeData(ByteBuffer fileData) {
		int counter;
		
		fileData.position(baseAdress-DataFileCreator.BASE_MEMORY_ADRESS);
		
		fileData.putShort((short)fieldTable.size());                        //  2 Bytes
		fileData.putShort((short)0);	                                    //  2 Bytes
		
		for (counter=0;counter < fieldTable.size();counter++) {
			fileData.putInt(fieldTable.get(counter).getBaseAddress());      //  4 Bytes * size
		}                                                                   //-----------------
		                                                                    //  4 Bytes  (size+1)
		for (counter=0;counter<fieldTable.size();counter++) {
			fieldTable.get(counter).writeData(fileData);
		}
	}
	*/
}
